#pragma once
#include <cmath>
#include <vector>
#include "Core\Item.h"
#include "Includes\SDefine.h"
#include "Tools\Ref.h"
#include "Tools\Serialization.h"
namespace SakuraAge {
#define PI 3.14159265
#define DEG2RAD (PI / 180)
#define RAD2DEG (180 / PI)
struct Vector2 {
  float x;
  float y;

  Vector2() : x(0), y(0){};
  Vector2(float x, float y) : x(x), y(y){};
  Vector2(const Vector2& value) : x(value.x), y(value.y){};

  float magnitude() const;
  Vector2 normalized() const;
  void Normalized();

  Vector2 operator+(const Vector2& a) const;
  Vector2 operator-(const Vector2& a) const;
  Vector2 operator*(float a) const;
  Vector2 operator/(float a) const;

  Vector2 operator+=(const Vector2& a);
  Vector2 operator-=(const Vector2& a);
  Vector2 operator*=(float a);
  Vector2 operator/=(float a);

  void RotateAround(const Vector2&center,float angle);
  void RotateAround_a(const Vector2& center, float angle);
  void Rotate(float angle);
  void Rotate_a(float angle);



  friend SerializedStream& operator&(SerializedStream&, const Vector2&);

  static float Dot(const Vector2& lhs, const Vector2& rhs) {
    return lhs.x * rhs.x + lhs.y * rhs.y;
  }
  
  static Vector2 RotateAround(const Vector2& p, const Vector2& center,
                              float angle) {
    Vector2 r;
    float a = (p.x - center.x), b = (p.y - center.y);
    r.x = (a)*cosf(angle) - (b)*sinf(angle) + center.x;
    r.y = (a)*sinf(angle) + (b)*cosf(angle) + center.y;
    return r;
  }
  static Vector2 RotateAround_a(const Vector2& p, const Vector2& center,
                              float angle) {
    Vector2 r;
    angle = (float)angle * PI / 180;
    float a = (p.x - center.x), b = (p.y - center.y);
    r.x = (a)*cosf(angle) - (b)*sinf(angle) + center.x;
    r.y = (a)*sinf(angle) + (b)*cosf(angle) + center.y;
    return r;
  }
  static Vector2 Rotate(const Vector2& p, float angle) {
    Vector2 r;
    r.x = (p.x) * cosf(angle) - (p.y) * sinf(angle);
    r.y = (p.x) * sinf(angle) + (p.y) * cosf(angle);
    return r;
  }
  static Vector2 Rotate_a(const Vector2& p, float angle) {
    Vector2 r;
    angle = (float)angle * PI / 180;
    r.x = (p.x) * cosf(angle) - (p.y) * sinf(angle);
    r.y = (p.x) * sinf(angle) + (p.y) * cosf(angle);
    return r;
  }
};

class Transform : public Component, RefBase<Transform> {
  friend class Component;
  friend class ItemFactor;
  friend class RefBase<Transform>;

  Transform();

 protected:
  virtual Vector2 GetPosition();
  virtual void SetPosition(Vector2 value);

  virtual float GetRotation();
  virtual void SetRotation(float value);

  virtual Vector2 GetScale();
  virtual void SetScale(Vector2 value);

 public:
  Vector2 local_position;
  float local_rotation;
  Vector2 local_scale;

  ObjRef<Transform> father;

  std::vector<ObjRef<Transform>> children;

  Transform& RotateDeg(float angle);
  Transform& RotateRad(float angle);
  Transform& Move(const Vector2& value);
  Transform& Translate(const Vector2& value);

  Vector2 RotateAround(float angle);
  virtual void Serialize(SerializedStream& ss);

  PROPERTY(Vector2, position);
  GET(position) { return GetPosition(); }
  SET(position) { SetPosition(value); }

  PROPERTY(float, rotation);
  GET(rotation) { return GetRotation(); }
  SET(rotation) { SetRotation(value); }

  PROPERTY(Vector2, scale);
  GET(scale) { return GetScale(); }
  SET(scale) { SetScale(value); }
};
}  // namespace SakuraAge
